home *** CD-ROM | disk | FTP | other *** search
- /*
- * lfsDescMap.c --
- *
- * Routines providing access fields to the LFS descriptor map.
- * This modules responsible for cacheing, writing, and checkpointing the
- * LFS descriptor map for a file system.
- *
- * Copyright 1989 Regents of the University of California
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any purpose and without
- * fee is hereby granted, provided that the above copyright
- * notice appear in all copies. The University of California
- * makes no representations about the suitability of this
- * software for any purpose. It is provided "as is" without
- * express or implied warranty.
- */
-
- #ifndef lint
- static char rcsid[] = "$Header: /sprite/src/kernel/lfs/RCS/lfsDescMap.c,v 1.7 91/08/08 17:44:41 mendel Exp $ SPRITE (Berkeley)";
- #endif /* not lint */
-
- #include <sprite.h>
- #include <lfs.h>
- #include <lfsInt.h>
- #include <lfsDescMap.h>
- #include <lfsDesc.h>
- #include <lfsStableMemInt.h>
- #include <lfsSeg.h>
- #include <fsutil.h>
-
-
- /*
- *----------------------------------------------------------------------
- *
- * LfsDescMapGetVersion --
- *
- * Return the descriptor map truncate version for the specified
- * file.
- *
- * Results:
- * SUCCESS if the entry is resident in the descriptor map.
- * FS_FILE_NOT_FOUND if the file is not allocated.
- * GEN_INVALID_ARG if the fileNumber is not available in the map.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- ReturnStatus
- LfsDescMapGetVersion(lfsPtr, fileNumber, versionNumPtr)
- Lfs *lfsPtr; /* File system of descriptor. */
- int fileNumber; /* File number of descriptor. */
- unsigned short *versionNumPtr; /* Area to return version number in.*/
- {
- LfsDescMap *mapPtr = &(lfsPtr->descMap);
- LfsStableMemEntry smemEntry;
- LfsDescMapEntry *entryPtr;
- ReturnStatus status;
-
- status = LfsStableMemFetch(&(mapPtr->stableMem), fileNumber, 0,
- &smemEntry);
- if (status != SUCCESS) {
- return status;
- }
- entryPtr = (LfsDescMapEntry *) LfsStableMemEntryAddr(&smemEntry);
-
- if (!(entryPtr->flags & LFS_DESC_MAP_ALLOCED)) {
- status = FS_FILE_NOT_FOUND;
- } else {
- *versionNumPtr = entryPtr->truncVersion;
- }
- LfsStableMemRelease(&(mapPtr->stableMem), &smemEntry, FALSE);
- return status;
-
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * LfsDescMapIncVersion --
- *
- * Increment the truncate version number for the specified
- * file.
- *
- * Results:
- * SUCCESS if the entry is resident in the descriptor map.
- * GEN_INVALID_ARG if the fileNumber is not available in the map.
- *
- * Side effects:
- * Version number of entry increment.
- *
- *----------------------------------------------------------------------
- */
-
- ReturnStatus
- LfsDescMapIncVersion(lfsPtr, fileNumber, versionPtr)
- Lfs *lfsPtr; /* File system of descriptor. */
- int fileNumber; /* File number of descriptor. */
- int *versionPtr; /* OUT: New truncate version number. */
- {
- LfsDescMap *mapPtr = &(lfsPtr->descMap);
- LfsDescMapEntry *entryPtr;
- ReturnStatus status;
- LfsStableMemEntry smemEntry;
-
- status = LfsStableMemFetch(&(mapPtr->stableMem), fileNumber,
- LFS_STABLE_MEM_MAY_DIRTY, &smemEntry);
- if (status != SUCCESS) {
- return status;
- }
- entryPtr = (LfsDescMapEntry *) LfsStableMemEntryAddr(&smemEntry);
-
- *versionPtr = ++(entryPtr->truncVersion);
- LfsStableMemRelease(&(mapPtr->stableMem), &smemEntry, TRUE);
- return SUCCESS;
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * LfsDescMapGetDiskAddr --
- *
- * Return the disk address of the specified descriptor.
- *
- * Results:
- * SUCCESS if the entry is resident in the descriptor map.
- * FS_FILE_NOT_FOUND if the file is not allocated.
- * GEN_INVALID_ARG if the fileNumber is not available in the map.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- ReturnStatus
- LfsDescMapGetDiskAddr(lfsPtr, fileNumber, diskAddrPtr)
- Lfs *lfsPtr; /* File system of descriptor. */
- int fileNumber; /* File number of descriptor. */
- LfsDiskAddr *diskAddrPtr; /* Current disk address.*/
- {
- LfsDescMap *mapPtr = &(lfsPtr->descMap);
- LfsDescMapEntry *entryPtr;
- ReturnStatus status;
- LfsStableMemEntry smemEntry;
-
- status = LfsStableMemFetch(&(mapPtr->stableMem), fileNumber, 0,
- &smemEntry);
- if (status != SUCCESS) {
- return status;
- }
- entryPtr = (LfsDescMapEntry *) LfsStableMemEntryAddr(&smemEntry);
-
- if (!(entryPtr->flags & LFS_DESC_MAP_ALLOCED)) {
- status = FS_FILE_NOT_FOUND;
- }
- *diskAddrPtr = entryPtr->blockAddress;
- LfsStableMemRelease(&(mapPtr->stableMem), &smemEntry, FALSE);
- return status;
-
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * LfsDescMapSetDiskAddr --
- *
- * Set the disk address for the specified descriptor.
- *
- * Results:
- * SUCCESS if the entry is resident in the descriptor map.
- * FAILURE if the fileNumber is not available in the map.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- ReturnStatus
- LfsDescMapSetDiskAddr(lfsPtr, fileNumber, diskAddr)
- Lfs *lfsPtr; /* File system of descriptor. */
- int fileNumber; /* File number of descriptor. */
- LfsDiskAddr diskAddr; /* New disk address.*/
- {
- LfsDescMap *mapPtr = &(lfsPtr->descMap);
- LfsDescMapEntry *entryPtr;
- ReturnStatus status;
- LfsStableMemEntry smemEntry;
-
- status = LfsStableMemFetch(&(mapPtr->stableMem), fileNumber,
- LFS_STABLE_MEM_MAY_DIRTY, &smemEntry);
- if (status != SUCCESS) {
- return status;
- }
- entryPtr = (LfsDescMapEntry *) LfsStableMemEntryAddr(&smemEntry);
-
- if (!(entryPtr->flags & LFS_DESC_MAP_ALLOCED)) {
- status = FAILURE;
- } else {
- if (!LfsIsNullDiskAddr(entryPtr->blockAddress)) {
- LfsSegUsageFreeBlocks(lfsPtr, sizeof(LfsFileDescriptor), 1,
- &entryPtr->blockAddress);
- LFS_STATS_INC(lfsPtr->stats.desc.descMoved);
- }
- entryPtr->blockAddress = diskAddr;
- }
- LfsStableMemRelease(&(mapPtr->stableMem), &smemEntry, (status == SUCCESS));
- return status;
-
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * LfsDescMapGetAccessTime --
- *
- * Return the file access time for the specified file number.
- *
- * Results:
- * SUCCESS if the entry is resident in the descriptor map.
- * FAILURE if the fileNumber is not available in the map.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- ReturnStatus
- LfsDescMapGetAccessTime(lfsPtr, fileNumber, accessTimePtr)
- Lfs *lfsPtr; /* File system of descriptor. */
- int fileNumber; /* File number of descriptor. */
- int *accessTimePtr; /* Current access time.*/
- {
- LfsDescMap *mapPtr = &(lfsPtr->descMap);
- LfsDescMapEntry *entryPtr;
- ReturnStatus status;
- LfsStableMemEntry smemEntry;
-
- status = LfsStableMemFetch(&(mapPtr->stableMem), fileNumber, 0,
- &smemEntry);
- if (status != SUCCESS) {
- return status;
- }
- entryPtr = (LfsDescMapEntry *) LfsStableMemEntryAddr(&smemEntry);
-
- if (!(entryPtr->flags & LFS_DESC_MAP_ALLOCED)) {
- status = FAILURE;
- }
- *accessTimePtr = entryPtr->accessTime;
- LfsStableMemRelease(&(mapPtr->stableMem), &smemEntry, FALSE);
- return status;
-
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * LfsDescMapSetAccessTime --
- *
- * Set the file access time for the specified file number.
- *
- * Results:
- * SUCCESS if the entry is resident in the descriptor map.
- * FAILURE if the fileNumber is not available in the map.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- ReturnStatus
- LfsDescMapSetAccessTime(lfsPtr, fileNumber, accessTime)
- Lfs *lfsPtr; /* File system of descriptor. */
- int fileNumber; /* File number of descriptor. */
- int accessTime; /* New current access time.*/
- {
- LfsDescMap *mapPtr = &(lfsPtr->descMap);
- LfsDescMapEntry *entryPtr;
- ReturnStatus status;
- LfsStableMemEntry smemEntry;
-
- status = LfsStableMemFetch(&(mapPtr->stableMem), fileNumber,
- LFS_STABLE_MEM_MAY_DIRTY, &smemEntry);
- if (status != SUCCESS) {
- return status;
- }
- entryPtr = (LfsDescMapEntry *) LfsStableMemEntryAddr(&smemEntry);
-
- if (!(entryPtr->flags & LFS_DESC_MAP_ALLOCED)) {
- status = FAILURE;
- } else {
- entryPtr->accessTime = accessTime;
- }
- LfsStableMemRelease(&(mapPtr->stableMem), &smemEntry, (status == SUCCESS));
-
- return status;
-
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Lfs_GetNewFileNumber --
- *
- * Allocate an used file number for a newly created file or directory.
- *
- * Results:
- * An error if could not find a free file descriptor.
- * SUCCESS if a file number can be allocate.
- * FAILURE if all available file numbers are taken.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- ReturnStatus
- Lfs_GetNewFileNumber(domainPtr, dirFileNum, fileNumberPtr)
- Fsdm_Domain *domainPtr; /* Domain to allocate the file
- * descriptor out of. */
- int dirFileNum; /* File number of the directory that
- * the file is in. -1 means that
- * this file descriptor is being
- * allocated for a directory. */
- int *fileNumberPtr; /* Place to return the file number allocated. */
- {
- Lfs *lfsPtr = LfsFromDomainPtr(domainPtr);
- LfsDescMap *mapPtr = &(lfsPtr->descMap);
- register LfsDescMapEntry *entryPtr;
- register int maxNumDesc, startDesc, i;
- Boolean found = FALSE;
- ReturnStatus status;
- static int dirSeed = 0;
- LfsStableMemEntry smemEntry;
-
- maxNumDesc = mapPtr->params.maxDesc;
- LFS_STATS_INC(lfsPtr->stats.desc.getNewFileNumber);
- if (dirFileNum == -1) {
- if (dirSeed == 0) {
- dirSeed = Fsutil_TimeInSeconds();
- }
- /*
- * Search linearly from a random starting descriptor.
- */
- startDesc = ((dirSeed * 1103515245 + 12345) & 0x7fffffff) %
- maxNumDesc;
- dirSeed++;
- } else {
- startDesc = dirFileNum;
- }
- status = LfsStableMemFetch(&(mapPtr->stableMem), startDesc,
- LFS_STABLE_MEM_MAY_DIRTY,
- &smemEntry);
- if (status != SUCCESS) {
- return status;
- }
- entryPtr = (LfsDescMapEntry *) LfsStableMemEntryAddr(&smemEntry);
- i = startDesc;
- do {
- if (!(entryPtr->flags & LFS_DESC_MAP_ALLOCED)) {
- found = TRUE;
- break;
- }
- LFS_STATS_INC(lfsPtr->stats.desc.scans);
- i++;
- if (i == maxNumDesc) {
- i = 0;
- }
- status = LfsStableMemFetch(&(mapPtr->stableMem), i,
- (LFS_STABLE_MEM_MAY_DIRTY|
- LFS_STABLE_MEM_REL_ENTRY), &smemEntry);
- if (status != SUCCESS) {
- return status;
- }
- entryPtr = (LfsDescMapEntry *) LfsStableMemEntryAddr(&smemEntry);
- } while (i != startDesc);
- if (!found) {
- LfsStableMemRelease(&(mapPtr->stableMem), &smemEntry, FALSE);
- printf( "Out of file descriptors.\n");
- return FAILURE;
- }
- mapPtr->checkPoint.numAllocDesc++;
- LfsSetNilDiskAddr(&entryPtr->blockAddress);
- entryPtr->flags = LFS_DESC_MAP_ALLOCED;
- *fileNumberPtr = i;
- LfsStableMemRelease(&(mapPtr->stableMem), &smemEntry, TRUE);
- return SUCCESS;
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Lfs_FreeFileNumber() --
- *
- * Mark a file number as unused and make it available for re-allocation.
- *
- * Results:
- * SUCCESS if a file number was not allocated.
- * FAILURE if all available file numbers are taken.
- *
- * Side effects:
- * Descriptor map entry is modified for the file.
- *
- *----------------------------------------------------------------------
- */
-
- ReturnStatus
- Lfs_FreeFileNumber(domainPtr, fileNumber)
- Fsdm_Domain *domainPtr; /* Domain of the file descriptor. */
- int fileNumber; /* File number to free. */
- {
- Lfs *lfsPtr = LfsFromDomainPtr(domainPtr);
- LfsDescMap *mapPtr = &(lfsPtr->descMap);
- LfsDescMapEntry *entryPtr;
- ReturnStatus status;
- LfsStableMemEntry smemEntry;
-
- LFS_STATS_INC(lfsPtr->stats.desc.free);
-
- status = LfsStableMemFetch(&(mapPtr->stableMem), fileNumber,
- LFS_STABLE_MEM_MAY_DIRTY, &smemEntry);
- if (status != SUCCESS) {
- return status;
- }
- entryPtr = (LfsDescMapEntry *) LfsStableMemEntryAddr(&smemEntry);
-
- if (!(entryPtr->flags & LFS_DESC_MAP_ALLOCED)) {
- status = FAILURE;
- } else {
- entryPtr->flags &= ~LFS_DESC_MAP_ALLOCED;
- LfsSegUsageFreeBlocks(lfsPtr, sizeof(LfsFileDescriptor), 1,
- &entryPtr->blockAddress);
- LfsSetNilDiskAddr(&entryPtr->blockAddress);
- mapPtr->checkPoint.numAllocDesc--;
- }
- LfsStableMemRelease(&(mapPtr->stableMem), &smemEntry, (status == SUCCESS));
- return status;
- }
-
-
-
- extern ReturnStatus LfsDescMapAttach _ARGS_((Lfs *lfsPtr, int checkPointSize,
- char *checkPointPtr));
- extern Boolean LfsDescMapCheckpoint _ARGS_((LfsSeg *segPtr, int flags,
- char *checkPointPtr, int *checkPointSizePtr,
- ClientData *clientDataPtr));
- extern Boolean LfsDescMapLayout _ARGS_((LfsSeg *segPtr, int flags,
- ClientData *clientDataPtr));
- extern void LfsDescMapWriteDone _ARGS_((LfsSeg *segPtr, int flags,
- ClientData *clientDataPtr));
- extern Boolean LfsDescMapClean _ARGS_((LfsSeg *segPtr, int *sizePtr,
- int *numCacheBlocksPtr, ClientData *clientDataPtr));
- extern ReturnStatus LfsDescMapDetach _ARGS_((Lfs *lfsPtr));
-
- static LfsSegIoInterface descMapIoInterface =
- { LfsDescMapAttach, LfsDescMapLayout, LfsDescMapClean,
- LfsDescMapCheckpoint, LfsDescMapWriteDone, LfsDescMapDetach, 0};
-
-
- /*
- *----------------------------------------------------------------------
- *
- * LfsDescMapInit --
- *
- * Initialize the the descriptor map data structures.
- *
- * Results:
- * None
- *
- * Side effects:
- *
- *----------------------------------------------------------------------
- */
-
- void
- LfsDescMapInit()
- {
- LfsSegIoRegister(LFS_DESC_MAP_MOD,&descMapIoInterface);
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * DescMapAttach --
- *
- * Attach routine for the descriptor map. Creates and initializes the
- * map for this file system.
- *
- * Results:
- * SUCCESS if attaching is going ok.
- *
- * Side effects:
- * Many
- *
- *----------------------------------------------------------------------
- */
-
- ReturnStatus
- LfsDescMapAttach(lfsPtr, checkPointSize, checkPointPtr)
- Lfs *lfsPtr; /* File system for attach. */
- int checkPointSize; /* Size of checkpoint data. */
- char *checkPointPtr; /* Data from last checkpoint before shutdown. */
- {
- LfsDescMap *mapPtr = &(lfsPtr->descMap);
- LfsDescMapCheckPoint *cp = (LfsDescMapCheckPoint *) checkPointPtr;
- ReturnStatus status;
- int size;
-
- /*
- * Allocate and fill in memory data structure for descriptor map.
- */
- mapPtr->params = lfsPtr->superBlock.descMap;
- mapPtr->checkPoint = *cp;
- /*
- * Load the index and buffer using the LfsStableMem routines.
- */
- size = sizeof(LfsDescMapCheckPoint);
- status = LfsStableMemLoad(lfsPtr, &(mapPtr->params.stableMem),
- checkPointSize - size,
- checkPointPtr + size,
- &(mapPtr->stableMem));
- if (status != SUCCESS) {
- LfsError(lfsPtr, status, "Can't loading descriptor map index\n");
- return status;
- }
-
- printf("LfsDescMapAttach - %d allocated descriptors.\n",
- mapPtr->checkPoint.numAllocDesc);
- return status;
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * DescMapDetach --
- *
- * Detach routine for the descriptor map. Destory the
- * map for this file system.
- *
- * Results:
- * SUCCESS if attaching is going ok.
- *
- * Side effects:
- * Many
- *
- *----------------------------------------------------------------------
- */
-
- ReturnStatus
- LfsDescMapDetach(lfsPtr)
- Lfs *lfsPtr; /* File system for attach. */
- {
- LfsDescMap *mapPtr = &(lfsPtr->descMap);
- return LfsStableMemDestory(lfsPtr, &(mapPtr->stableMem));
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * DescMapCheckpoint --
- *
- * Routine to handle checkpointing of the descriptor map data.
- *
- * Results:
- * TRUE if more data needs to be written, FALSE if this module is
- * checkpointed.
- *
- * Side effects:
- * Many
- *
- *----------------------------------------------------------------------
- */
-
- Boolean
- LfsDescMapCheckpoint(segPtr, flags, checkPointPtr, checkPointSizePtr,
- clientDataPtr)
- LfsSeg *segPtr; /* Segment containing data for checkpoint. */
- int flags; /* Flags for shutdown */
- char *checkPointPtr; /* Buffer to write checkpoint data. */
- int *checkPointSizePtr; /* Bytes added to the checkpoint area.*/
- ClientData *clientDataPtr;
- {
- Lfs *lfsPtr = segPtr->lfsPtr;
- LfsDescMap *mapPtr = &(lfsPtr->descMap);
- LfsDescMapCheckPoint *cp = (LfsDescMapCheckPoint *) checkPointPtr;
- int size, dataSize;
- Boolean full;
-
- *cp = mapPtr->checkPoint;
- size = sizeof(LfsDescMapCheckPoint);
- dataSize = 0;
- full = LfsStableMemCheckpoint(segPtr, checkPointPtr + size, flags,
- &dataSize, clientDataPtr, &(mapPtr->stableMem));
- if (!full) {
- (*checkPointSizePtr) = dataSize + size;
- }
- return full;
-
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * LfsDescMapLayout --
- *
- * Routine to handle writing of the descriptor map data.
- *
- * Results:
- * TRUE if more data needs to be written, FALSE if this module is
- * statisified
- *
- * Side effects:
- * Many
- *
- *----------------------------------------------------------------------
- */
- Boolean
- LfsDescMapLayout(segPtr, flags, clientDataPtr)
- LfsSeg *segPtr; /* Segment to place data blocks in. */
- int flags; /* Flags. */
- ClientData *clientDataPtr;
- {
- Lfs *lfsPtr = segPtr->lfsPtr;
- LfsDescMap *mapPtr = &(lfsPtr->descMap);
-
- if ((flags & LFS_CLEANING_LAYOUT) != 0) {
- return FALSE;
- }
- return LfsStableMemLayout(segPtr, flags, clientDataPtr, &(mapPtr->stableMem));
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * DescWriteDone --
- *
- * Routine to handle finishing of a checkpoint.
- *
- * Results:
- * None
- *
- * Side effects:
- * Many
- *
- *----------------------------------------------------------------------
- */
-
- void
- LfsDescMapWriteDone(segPtr, flags, clientDataPtr)
- LfsSeg *segPtr; /* Segment containing data for checkpoint. */
- int flags; /* Flags for checkpoint */
- ClientData *clientDataPtr;
- {
- Lfs *lfsPtr = segPtr->lfsPtr;
- LfsDescMap *mapPtr = &(lfsPtr->descMap);
-
- LFS_STATS_ADD(lfsPtr->stats.desc.mapBlocksWritten,
- (LfsSegSummaryBytesLeft(segPtr) / sizeof(int)));
-
- LfsStableMemWriteDone(segPtr, flags, clientDataPtr, &(mapPtr->stableMem));
- return;
-
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * DescMapClean --
- *
- * Routine to handle cleaning of descriptor map data.
- *
- * Results:
- * TRUE if more data needs to be written, FALSE if this module is
- * happy for the time being.
- *
- * Side effects:
- *
- *
- *----------------------------------------------------------------------
- */
-
- Boolean
- LfsDescMapClean(segPtr, sizePtr, numCacheBlocksPtr, clientDataPtr)
- LfsSeg *segPtr; /* Segment containing data to clean. */
- int *sizePtr; /* Segment to place data blocks in. */
- int *numCacheBlocksPtr;
- ClientData *clientDataPtr;
- {
- Lfs *lfsPtr = segPtr->lfsPtr;
- LfsDescMap *mapPtr = &(lfsPtr->descMap);
- Boolean full;
-
- full = LfsStableMemClean(segPtr, sizePtr, numCacheBlocksPtr,
- clientDataPtr, &(mapPtr->stableMem));
-
- LFS_STATS_ADD(lfsPtr->stats.desc.mapBlockCleaned,
- *sizePtr/mapPtr->stableMem.params.blockSize);
- return full;
- }
-
-